home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 2848 / 2848.xpi / chrome / passwordexporter.jar / content / pwdex-passwordmanager.js < prev    next >
Text File  |  2009-08-04  |  30KB  |  593 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Password Exporter
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  *    Justin Scott <fligtar@gmail.com>.
  18.  *
  19.  * Portions created by the Initial Developer are Copyright (C) 2006
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s): (none)
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. /**
  39.  * Password Exporter - Password Manager support
  40.  * This file is for use with the password manager in Firefox 1.5/2 and Thunderbird
  41.  */
  42.  
  43. var passwordExporterPasswordMgr = {
  44.     export: {
  45.         currentExport: '', // CSV or XML string of current export
  46.         count: 0, // count of exported logins
  47.         errorCount: 0, // count of failed logins
  48.         failed: '', // failed hosts
  49.         
  50.         // starts export of saved passwords to XML/CSV file
  51.         start: function() {
  52.             passwordExporter.debug('Starting Export...');
  53.             
  54.             // Check if user has accepted agreement
  55.             passwordExporter.checkAgreement();
  56.             
  57.             if (passwordExporter.accepted == true) {
  58.                 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  59.                 var stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  60.                 
  61.                 // Prompt user to select where to save the export
  62.                 fp.init(window, passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-title'), fp.modeSave);
  63.                 fp.defaultString = 'password-export-' + passwordExporter.getDateString();
  64.                 fp.defaultExtension = '.xml';
  65.                 fp.appendFilter(passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-save-xml'), '*.xml');
  66.                 fp.appendFilter(passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-save-csv'), '*.csv');
  67.                 
  68.                 // If cancelled, return
  69.                 if (fp.show() == fp.returnCancel)
  70.                     return;
  71.                 
  72.                 // Remove file if it exists
  73.                 if (fp.file.exists())
  74.                     fp.file.remove(true);
  75.                     
  76.                 fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);
  77.                 stream.init(fp.file, 0x02, 0x200, null);
  78.                 
  79.                 // Whether to encrypt the passwords
  80.                 var encrypt = document.getElementById('pwdex-encrypt').checked;
  81.                 
  82.                 // do export
  83.                 if (fp.filterIndex == 0)
  84.                     var content = this.export('xml', encrypt);
  85.                 else if (fp.filterIndex == 1)
  86.                     var content = this.export('csv', encrypt);
  87.                 
  88.                 stream.write(content, content.length);
  89.                 stream.close();
  90.                 
  91.                 passwordExporter.debug('Export of ' + this.count + ' entries completed with ' + this.errorCount + ' errors.');
  92.                 
  93.                 if (this.errorCount == 0)
  94.                     alert(passwordExporter.bundle.formatStringFromName('passwordexporter.alert-passwords-exported', [this.count], 1));
  95.                 else {
  96.                     var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  97.                     
  98.                     var flags = promptService.BUTTON_TITLE_OK * promptService.BUTTON_POS_0 +
  99.                     promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1;
  100.                     
  101.                     var response = promptService.confirmEx(window, passwordExporter.bundle.GetStringFromName('passwordexporter.name'),
  102.                                     passwordExporter.bundle.formatStringFromName('passwordexporter.alert-passwords-exported', [this.count], 1) + "\n\n" +
  103.                                     passwordExporter.bundle.formatStringFromName('passwordexporter.alert-passwords-failed', [this.errorCount], 1), flags,
  104.                                     null, passwordExporter.bundle.GetStringFromName('passwordexporter.show-details'), null, null, {});
  105.                     
  106.                     if (response == 1)
  107.                         window.openDialog("chrome://passwordexporter/content/pwdex-details-export.xul", "","chrome,resizable,centerscreen,close=no,modal");
  108.                 }
  109.             }
  110.         },
  111.     
  112.         // Generates XML/CSV from Password/Login Manager entries
  113.         export: function(type, encrypt) {
  114.             passwordExporter.debug('Generating ' + type + ' entries...');
  115.             if (type == 'xml') {
  116.                 this.currentExport = '<xml>' + passwordExporter.linebreak;
  117.                 this.currentExport += '<entries ext="Password Exporter" extxmlversion="1.1" type="saved" encrypt="' + encrypt + '">' + passwordExporter.linebreak;
  118.             }
  119.             else if (type == 'csv') {
  120.                 this.currentExport = '# Generated by Password Exporter; Export format 1.1; Encrypted: ' + encrypt + passwordExporter.linebreak;
  121.                 this.currentExport += '"hostname","username","password","formSubmitURL","httpRealm","usernameField","passwordField"' + passwordExporter.linebreak;
  122.             }
  123.             
  124.             this.count = 0;
  125.             this.errorCount = 0;
  126.             passwordExporter.failed = '';
  127.             
  128.             var passwordManager = CC_passwordManager.createInstance();
  129.             passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  130.             passwordManager.QueryInterface(Components.interfaces.nsIPasswordManagerInternal);
  131.             
  132.             var nextPassword;
  133.             var enumerator = passwordManager.enumerator;
  134.             
  135.             while (enumerator.hasMoreElements()) {
  136.                 try {
  137.                     if (Components.interfaces.nsIPasswordInternal)
  138.                         nextPassword = enumerator.getNext().QueryInterface(Components.interfaces.nsIPasswordInternal);
  139.                     else
  140.                         nextPassword = enumerator.getNext().QueryInterface(Components.interfaces.nsIPassword);
  141.                     
  142.                     if (nextPassword.formSubmitURL)
  143.                         var formSubmitURL = nextPassword.formSubmitURL;
  144.                     else
  145.                         var formSubmitURL = null;
  146.                     
  147.                     if (type == 'xml') {
  148.                         this.entryToXML(nextPassword.host, formSubmitURL, null, nextPassword.user, nextPassword.userFieldName,
  149.                                     nextPassword.password, nextPassword.passwordFieldName, encrypt);
  150.                     }
  151.                     else if (type == 'csv') {
  152.                         this.entryToCSV(nextPassword.host, formSubmitURL, null, nextPassword.user, nextPassword.userFieldName,
  153.                                     nextPassword.password, nextPassword.passwordFieldName, encrypt);
  154.                     }
  155.                 } catch (e) {
  156.                     this.errorCount++;
  157.                     try {
  158.                         this.failed += nextPassword.host + passwordExporter.linebreak;
  159.                     } catch (e) { }
  160.                 }
  161.             }
  162.             
  163.             if (type == 'xml') {
  164.                 this.currentExport += '</entries>' + passwordExporter.linebreak + '</xml>';
  165.             }
  166.             
  167.             return this.currentExport;
  168.         },
  169.         
  170.         // Records an nsILoginInfo or nsIPassword entry to XML
  171.         entryToXML: function(hostname, formSubmitURL, httpRealm, username, usernameField,
  172.                             password, passwordField, encrypt) {
  173.             if (encrypt) {
  174.                 username = btoa(username);
  175.                 password = btoa(password);
  176.             }
  177.             
  178.             try {
  179.                 var xml  = '<entry';
  180.                 xml += ' host="' + this.escapeQuote(hostname) + '"';
  181.                 xml += ' user="' + this.escapeQuote(username) + '"';
  182.                 xml += ' password="' + this.escapeQuote(password) + '"';
  183.                 
  184.                 xml += ' formSubmitURL="' + (formSubmitURL ? this.escapeQuote(formSubmitURL) : '') + '"';
  185.                 xml += ' httpRealm="' + (httpRealm ? this.escapeQuote(httpRealm) : '') + '"';
  186.                 xml += ' userFieldName="' + (usernameField ? this.escapeQuote(usernameField) : '') + '"';
  187.                 xml += ' passFieldName="' + (passwordField ? this.escapeQuote(passwordField) : '') + '"';
  188.                 
  189.                 xml += '/>' + passwordExporter.linebreak;
  190.                 
  191.                 this.currentExport += xml;
  192.                 this.count++;
  193.             } catch (e) {
  194.                 this.errorCount++;
  195.                 try {
  196.                     this.failed += hostname + passwordExporter.linebreak;
  197.                 } catch (e) { }
  198.             }
  199.         },
  200.         
  201.         // Records an nsILoginInfo or nsIPassword entry to CSV
  202.         entryToCSV: function(hostname, formSubmitURL, httpRealm, username, usernameField,
  203.                             password, passwordField, encrypt) {
  204.             if (encrypt) {
  205.                 username = btoa(username);
  206.                 password = btoa(password);
  207.             }
  208.             
  209.             try {
  210.                 var csv = '"' + this.escapeQuote(hostname) + '",';
  211.                 csv += '"' + this.escapeQuote(username) + '",';
  212.                 csv += '"' + this.escapeQuote(password) + '",';
  213.                 
  214.                 csv += '"' + (formSubmitURL ? this.escapeQuote(formSubmitURL) : '') + '",';
  215.                 csv += '"' + (httpRealm ? this.escapeQuote(httpRealm) : '') + '",';
  216.                 csv += '"' + (usernameField ? this.escapeQuote(usernameField) : '') + '",';
  217.                 csv += '"' + (passwordField ? this.escapeQuote(passwordField) : '')+ '"';
  218.                 
  219.                 csv += passwordExporter.linebreak;
  220.                 
  221.                 this.currentExport += csv;
  222.                 this.count++;
  223.             } catch (e) {
  224.                 this.errorCount++;
  225.                 try {
  226.                     this.failed += hostname + passwordExporter.linebreak;
  227.                 } catch (e) { }
  228.             }
  229.         },
  230.         
  231.         // escapes only quotes and ampersands so that it will parse correctly in XML
  232.         escapeQuote: function(string) {
  233.             string = string.replace(/%/gi, '%25');
  234.             string = string.replace(/</gi, '%3C');
  235.             string = string.replace(/>/gi, '%3E');
  236.             string = string.replace(/"/gi, '%22');
  237.             string = string.replace(/&/gi, '%26');
  238.             return string;
  239.         },
  240.         
  241.         // populate details textbox with failed entries
  242.         populateFailed: function(textbox) {
  243.             textbox.value = this.failed;
  244.         },
  245.         
  246.         disabled: {
  247.             // starts export of login disabled sites that never saved passwords
  248.             start: function() {
  249.                 passwordExporter.debug('Starting Disabled Hosts Export...');
  250.                 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  251.                 var stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  252.                 
  253.                 fp.init(window, passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-title'), fp.modeSave);
  254.                 fp.defaultString = 'disabled-export-' + passwordExporter.getDateString();
  255.                 fp.defaultExtension = '.xml';
  256.                 fp.appendFilters(fp.filterXML);
  257.                 
  258.                 // If cancelled, return
  259.                 if (fp.show() == fp.returnCancel)
  260.                     return;
  261.                 
  262.                 if (fp.file.exists())
  263.                     fp.file.remove(true);
  264.                 
  265.                 fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);
  266.                 stream.init(fp.file, 0x02, 0x200, null);
  267.                 
  268.                 var xml = this.export();
  269.                 
  270.                 stream.write(xml, xml.length);
  271.                 stream.close();
  272.                 
  273.                 passwordExporter.debug('Disabled hosts export complete.');
  274.                 
  275.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-rejected-exported'));
  276.             },
  277.             
  278.             // Gets disabled hosts from Password/Login Manager
  279.             export: function() {
  280.                 var xml = '<xml>' + passwordExporter.linebreak;
  281.                 xml += '<entries ext="Password Exporter" extxmlversion="1.0.2" type="rejected">' + passwordExporter.linebreak;
  282.                 
  283.                 var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"].createInstance();
  284.                 passwordManager = passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  285.                 
  286.                 var enumerator = passwordManager.rejectEnumerator;
  287.                 var nextPassword;
  288.                 
  289.                 while (enumerator.hasMoreElements()) {
  290.                     try {
  291.                         nextPassword = enumerator.getNext();
  292.                     } catch(e) {
  293.                         break;
  294.                     }
  295.                     
  296.                     nextPassword = nextPassword.QueryInterface(Components.interfaces.nsIPassword);
  297.                     
  298.                     xml += '<entry host="' + nextPassword.host + '"/>' + passwordExporter.linebreak;
  299.                 }
  300.                 
  301.                 xml += '</entries>' + passwordExporter.linebreak + '</xml>';
  302.                 
  303.                 return xml;
  304.             }
  305.         }
  306.     
  307.     },
  308.     
  309.     import: {
  310.         totalCount: 0, // total number of logins
  311.         currentCount: 0, // number of logins currently imported
  312.         
  313.         // Starts the import of logins from a CSV or XML file
  314.         start: function() {
  315.             passwordExporter.debug('Starting Import...');
  316.             
  317.             var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  318.             var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
  319.             var streamIO = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  320.             var input, inputArray, importType, doc, header, name, type, version, encrypt;
  321.             
  322.             fp.init(window, passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-title'), fp.modeOpen);
  323.             fp.appendFilter(passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-open-xmlcsv'), '*.xml; *.csv; *');
  324.             
  325.             // If cancelled, return
  326.             if (fp.show() == fp.returnCancel)
  327.                 return;
  328.             
  329.             stream.init(fp.file, 0x01, 0444, null);
  330.             streamIO.init(stream);
  331.             input = streamIO.read(stream.available());
  332.             streamIO.close();
  333.             stream.close();
  334.             
  335.             var parser = new DOMParser();
  336.             
  337.             // If CSV format, parse for header info
  338.             if (fp.file.path.indexOf('.csv') != -1) {
  339.                 // Starting in 1.1, header is in a "comment" at the top
  340.                 var header = /# Generated by (.+); Export format (.{3,6}); Encrypted: (true|false)/i.exec(input);
  341.                 if (!header) {
  342.                     // Previously, the header was in CSV form in the first line
  343.                     header = /(.+?),(.{3,6}),(true|false)/i.exec(input);
  344.                 }
  345.                 if (!header) {
  346.                     // If we still can't read header, there's a problem with the file
  347.                     alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-cannot-import'));
  348.                     return;
  349.                 }
  350.                 var properties = {'extension': header[1],
  351.                                   'importtype': 'saved',
  352.                                   'importversion': header[2],
  353.                                   'encrypt': header[3]};
  354.                 this.import('csv', properties, input);
  355.             }
  356.             // If XML format, parse for header info
  357.             else {
  358.                 var doc = parser.parseFromString(input, "text/xml");
  359.                 var header = doc.documentElement.getElementsByTagName('entries')[0];
  360.                 
  361.                 if (doc.documentElement.nodeName == 'parsererror') {
  362.                     alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-xml-error'));
  363.                     return;
  364.                 }
  365.                 
  366.                 var properties = {'extension': header.getAttribute('ext'),
  367.                                   'importtype': header.getAttribute('type'),
  368.                                   'importversion': header.getAttribute('extxmlversion'),
  369.                                   'encrypt': header.getAttribute('encrypt')};
  370.                 var entries = doc.documentElement.getElementsByTagName('entry');
  371.                 this.import('xml', properties, entries);
  372.             }
  373.         },
  374.         
  375.         // Validates import file and parses it
  376.         import: function (type, properties, entries) {
  377.             passwordExporter.debug(type + ' file read...');
  378.             
  379.             // Make sure this is a Password Exporter export
  380.             if (properties.extension != 'Password Exporter') {
  381.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-cannot-import'));
  382.                 return;
  383.             }
  384.             
  385.             // Make sure this is a saved passwords file, as opposed to disabled hosts
  386.             if (properties.importtype != 'saved') {
  387.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-wrong-file-reject'));
  388.                 return;
  389.             }
  390.             
  391.             // Make sure this was exported from a version supported (not a future version)
  392.             if (properties.importversion in {'1.0.2':'', '1.0.4':'', '1.1':''}) {
  393.                 // Import
  394.                 var logins = [];
  395.                 this.totalCount = 0;
  396.                 this.currentCount = 0;
  397.                 
  398.                 if (type == 'xml') {
  399.                     this.totalCount = entries.length;
  400.                     
  401.                     for (var i = 0; i < entries.length; i++) {
  402.                         var login = {
  403.                             'username': unescape(entries[i].getAttribute('user')),
  404.                             'password': unescape(entries[i].getAttribute('password')),
  405.                             'hostname': (entries[i].getAttribute('host') == null ? null : unescape(entries[i].getAttribute('host'))),
  406.                             'httpRealm': ((entries[i].getAttribute('httpRealm') == null || entries[i].getAttribute('httpRealm') == "") ? null : unescape(entries[i].getAttribute('httpRealm'))),
  407.                             'formSubmitURL': (entries[i].getAttribute('formSubmitURL') == null ? "" : unescape(entries[i].getAttribute('formSubmitURL'))),
  408.                             'usernameField': (entries[i].getAttribute('userFieldName') == null ? null : unescape(entries[i].getAttribute('userFieldName'))),
  409.                             'passwordField': (entries[i].getAttribute('passFieldName') == null ? null : unescape(entries[i].getAttribute('passFieldName')))
  410.                         };
  411.                         
  412.                         logins[i] = this.getFormattedLogin(properties, login);
  413.                     }
  414.                 }
  415.                 else if (type == 'csv') {
  416.                     if (/\r\n/i.test(entries))
  417.                         var entryArray = entries.split("\r\n");
  418.                     else if (/\r/i.test(entries))
  419.                         var entryArray = entries.split("\r");
  420.                     else
  421.                         var entryArray = entries.split("\n");
  422.                     
  423.                     // Prior to version 1.1, we only had one line of header
  424.                     // After 1.1, there was a header comment and a labels line
  425.                     if (properties.importversion == '1.0.2' || properties.importversion == '1.0.4')
  426.                         var start = 1;
  427.                     else
  428.                         var start = 2;
  429.                     
  430.                     this.totalCount = entryArray.length - 1;
  431.                     
  432.                     for (var i = start; i < (entryArray.length - 1); i++) {
  433.                         if (properties.importversion == '1.0.2' || properties.importversion == '1.0.4') {
  434.                             // Before version 1.1, csv didn't have quotes
  435.                             var fields = entryArray[i].split(',');
  436.                             
  437.                             var login = {
  438.                                 'hostname': (fields[0] == '' ? null : unescape(fields[0])),
  439.                                 'username': unescape(fields[1]),
  440.                                 'password': unescape(fields[2]),
  441.                                 'httpRealm': null,
  442.                                 'formSubmitURL': "",
  443.                                 'usernameField': (fields[3] == '' ? null : unescape(fields[3])),
  444.                                 'passwordField': (fields[4] == '' ? null : unescape(fields[4]))
  445.                             };
  446.                         }
  447.                         else {
  448.                             // Version 1.1 CSV has quotes and 2 new fields
  449.                             var fields = entryArray[i].split('","');
  450.                             
  451.                             var login = {
  452.                                 'hostname': (fields[0] == '"' ? null : unescape(fields[0].replace('"', ''))),
  453.                                 'formSubmitURL': (fields[3] == '' ? "" : unescape(fields[3])),
  454.                                 'httpRealm': (fields[4] == '' ? null : unescape(fields[4])),
  455.                                 'username': unescape(fields[1]),
  456.                                 'password': unescape(fields[2]),
  457.                                 'usernameField': (fields[5] == '' ? null : unescape(fields[5])),
  458.                                 'passwordField': (fields[6] == '"' ? null : unescape(fields[6].replace('"', '')))
  459.                             };
  460.                         }
  461.                         
  462.                         logins[(i - start)] = this.getFormattedLogin(properties, login);
  463.                     }
  464.                 }
  465.                 
  466.                 this.insertEntries(logins);
  467.                 
  468.                 if (document.getElementById('tabbox')) {
  469.                     // Refresh the listbox of passwords only if we are using the tab... the dialog version does not need to
  470.                     LoadSignons();
  471.                 }
  472.                 passwordExporter.debug('Import complete.');
  473.                 
  474.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-passwords-imported'));
  475.             }
  476.             else
  477.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-wrong-version'));
  478.         },
  479.         
  480.         // Makes sure logins are formatted correctly
  481.         getFormattedLogin: function(properties, login) {
  482.             passwordExporter.debug('pre-getFormattedLogin: [hostname: ' + login.hostname + ', httpRealm: ' + login.httpRealm + ', formSubmitURL: ' + login.formSubmitURL + ', usernameField: ' + login.usernameField + ', passwordField: ' + login.passwordField + ']');
  483.             
  484.             // in version 1.0.2, encryption was only for passwords... in 1.0.4 we encrypt usernames as well    
  485.             if (properties.encrypt == 'true') {
  486.                 login.password = atob(login.password);
  487.                 
  488.                 if (properties.importversion != '1.0.2')
  489.                     login.username = atob(login.username);
  490.             }
  491.             
  492.             // If there's a httpRealm, it's an export from Firefox 3
  493.             if (login.httpRealm != null)
  494.                 login.hostname += ' (' + login.httpRealm + ')';
  495.             
  496.             // There is no httpRealm to worry about before Firefox 3
  497.             if (login.formSubmitURL == null)
  498.                 login.formSubmitURL = '';
  499.             
  500.             passwordExporter.debug('post-getFormattedLogin: [hostname: ' + login.hostname + ', httpRealm: ' + login.httpRealm + ', formSubmitURL: ' + login.formSubmitURL + ', usernameField: ' + login.usernameField + ', passwordField: ' + login.passwordField + ']');
  501.             
  502.             return login;
  503.         },
  504.         
  505.         // Inserts the entries into Password Manager
  506.         insertEntries: function(entries) {
  507.             var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"].createInstance();
  508.             passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  509.             passwordManager.QueryInterface(Components.interfaces.nsIPasswordManagerInternal);
  510.             
  511.             for (var i = 0; i < entries.length; i++) {
  512.                 if (!passwordExporter.isThunderbird) {
  513.                     passwordManager.addUserFull(entries[i].hostname, entries[i].username, 
  514.                                                 entries[i].password, entries[i].usernameField,
  515.                                                 entries[i].passwordField);
  516.                 }
  517.                 else {
  518.                     passwordManager.addUser(entries[i].hostname, entries[i].username,
  519.                                             entries[i].password);
  520.                 }
  521.                 
  522.                 this.currentCount++;
  523.             }
  524.         },
  525.         
  526.         disabled: {
  527.             // Starts import of disabled hosts from XML file
  528.             start: function() {
  529.                 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  530.                 var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
  531.                 var streamIO = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  532.                 var input;
  533.                 
  534.                 fp.init(window, passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-title'), fp.modeOpen);
  535.                 fp.appendFilter(passwordExporter.bundle.GetStringFromName('passwordexporter.filepicker-open-xml'), '*.xml; *');
  536.                 
  537.                 // If canceled, return
  538.                 if (fp.show() == fp.returnCancel)
  539.                     return;
  540.                 
  541.                 stream.init(fp.file, 0x01, 0444, null);
  542.                 streamIO.init(stream);
  543.                 input = streamIO.read(stream.available());
  544.                 streamIO.close();
  545.                 stream.close();
  546.                 
  547.                 var parser = new DOMParser();
  548.                 var doc = parser.parseFromString(input, "text/xml");
  549.                 
  550.                 var header = doc.documentElement.getElementsByTagName('entries')[0];
  551.                 
  552.                 // Return if parser error or no header
  553.                 if (doc.documentElement.nodeName == 'parsererror' || !header) {
  554.                     alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-xml-error'));
  555.                     return;
  556.                 }
  557.                 
  558.                 // Return if not Password Exporter
  559.                 if (header.getAttribute('ext') != 'Password Exporter') {
  560.                     alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-cannot-import'));
  561.                     return;
  562.                 }
  563.                 
  564.                 // Make sure it's a disabled hosts file
  565.                 if (header.getAttribute('type') != 'rejected') {
  566.                     alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-wrong-file-saved'));
  567.                     return;
  568.                 }
  569.                 
  570.                 var entries = doc.documentElement.getElementsByTagName('entry');
  571.                 this.import(entries);
  572.                 
  573.                 if (document.getElementById('tabbox')) {
  574.                     // Refresh the listbox of rejects only if we are using the tab... the dialog version does not need to
  575.                     LoadRejects();
  576.                 }
  577.                 
  578.                 alert(passwordExporter.bundle.GetStringFromName('passwordexporter.alert-rejected-imported'));
  579.             },
  580.             
  581.             // Import disabled hosts
  582.             import: function(entries) {
  583.                 var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"].createInstance();
  584.                 passwordManager = passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  585.                 
  586.                 for (var i = 0; i < entries.length; i++) {
  587.                     passwordManager.addReject(entries[i].getAttribute('host'));
  588.                 }
  589.             }
  590.         }
  591.     }
  592. };
  593.